//==============================================================================
// HMM.hh
// ----------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
// $Id: $
//------------------------------------------------------------------------------
//
//==============================================================================
//.......1.........2.........3.........4.........5.........6.........7.........8
//

#include "LocalSTL.hh"
#include "Sequence.hh"
#include "Table.hh"
#include "RandomNumberGenerator.hh"

#ifndef _HMM
#define _HMM

//------------------------------------------------------------------------------
// * HMM
//------------------------------------------------------------------------------
// Implements a very simple hidden markov model.   This version has a number of 
// limitations that limit it's flexibility.  There is a more general hmm class in 
// the works which will be called HiddenMarkovModel, which will allow you to define 
// the alphabet and do other, more generalized, operations.  
//
//
class HMM{
public:

  Sequence mSequence;
  vector<string> mStateNames;
  
  Table<int>    mPtr;
  Table<double> mV;
  Table<double> mEmissionPr;
  Table<double> mTransitionPr;
  
  Table<double> mEmissionCount;
  Table<double> mTransitionCount;
  
  
  HMM(){};
  HMM(int states,int alphabet){
	 mNumStates = states;
	 mNumSymbols = alphabet;
	 mEmissionPr.Allocate(states,alphabet);
	 mTransitionPr.Allocate(states,alphabet);
	 mEmissionCount.Allocate(states,alphabet);
	 mTransitionCount.Allocate(states,alphabet);

	 for(int i = 0;i<mNumStates;i++){
		for(int j = 0;j< mNumSymbols;j++){
		  mEmissionCount[i][j] = 0;
		  mTransitionCount[i][j] = 0;
		}
	 }
  }
  
  
  int mSeqLength;
  int mNumStates;
  int mNumSymbols;
  
  double 	mPathProbability;
  int     mTracebackStart;
  
  void  LogTransform();
  void  LogTransform(Table<double> &DTable);
  
  char  bugChar(int symbol);

  // Setup for 
  void  SetupForPrediction(string &EmissionFile,string &TransitionFile,
				  Sequence &Sequence,vector<string> &StateNames);
  

  // Training from labled examples. 
  void UpdateEstimateFromCounts();
  void UpdateCounts(Sequence Seq,vector<int> Labels);


  void GetMostProbablePath(vector<int> &path);
  void GenerateSequenceFromModel(Sequence &SeqOut,
											vector<int> &StateOut,int size);
  
  void Viterbi();
  int  BaseIdx(char c);
  int  BaseIdx2(char c);
};

#endif
